package main
import (
	"fmt"
)
//channel 是引用类型，必须在make之后才能使用


func main(){
	//使用select可以解决从管道获取数据的阻塞问题！

	//1.定义一个管道10个int数据
	intchan := make(chan int,10)
	for i:=0;i<10;i++{
		intchan <- i
	}
	//2.定义一个管道5个string数据
	stringchan := make(chan string,5)
	for i:=0;i< 5;i++{
		stringchan <- "hello"+fmt.Sprintf("%d",i)
	}

	//传统方法在遍历管道时，如果不关闭会导致deadlock
	//在实际开发中，不确定什么时候关闭管道时！
	//label:
	for {
		select {
		//注意：如果intchan管道一直没有关闭，不会一直阻塞而死锁
		//如果管道取不到值，就会自动跳到下一个case
		case v := <- intchan :    
			fmt.Println("从intchan读取了数据：",v)
		case v := <- stringchan:
			fmt.Println("从stringchan读取了数据：",v)
		default:
			fmt.Println("所有管道都取不到值了，我走了！")	
			//break label	
			return
		}
	}
}


/*
channel使用细节和注意事项2：
	3、使用select可以解决从管道获取数据的阻塞问题！   //不知道什么时候close管道的情况下可以使用该方法！***********
		select {
		case v := <- Xxxchan:
			...
		case v := <- Xxxchan:
			...
		default:
			...
		}
	4、goroutine中使用recover，解决协程中出现panic，导致程序崩溃的问题！  如果协程不recover，会导致主程序崩溃


*/